package com.itjeffrey.autocode.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.itjeffrey.autocode.bo.ScheduleJobLogTbBO;
import com.itjeffrey.autocode.common.ACContext;
import com.itjeffrey.autocode.common.PageResult;
import com.itjeffrey.autocode.common.Result;
import com.itjeffrey.autocode.constant.SysConstant;
import com.itjeffrey.autocode.entity.ScheduleJobLogTbEntity;
import com.itjeffrey.autocode.enums.JobTypeEnum;
import com.itjeffrey.autocode.mapper.ScheduleJobLogTbMapper;
import com.itjeffrey.autocode.service.ScheduleJobLogTbService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itjeffrey.autocode.util.BeanOprUtils;
import com.itjeffrey.autocode.util.DateUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;

/**
 * 服务实现类
 * @author: admin
 * @date: 2021-06-18 01:11:12
 */
@Service
public class ScheduleJobLogTbServiceImpl extends ServiceImpl<ScheduleJobLogTbMapper, ScheduleJobLogTbEntity> implements ScheduleJobLogTbService {

    private static final Logger log = LoggerFactory.getLogger(ScheduleJobLogTbServiceImpl.class);

    @Resource
    private ScheduleJobLogTbMapper scheduleJobLogTbMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(ScheduleJobLogTbBO scheduleJobLogTbBO) {
        ScheduleJobLogTbEntity scheduleJobLogTbEntity = BeanOprUtils.copyProperties(scheduleJobLogTbBO,
                ScheduleJobLogTbEntity::new);
        scheduleJobLogTbMapper.insert(scheduleJobLogTbEntity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result delete(List<Integer> ids) {
        scheduleJobLogTbMapper.deleteBatchIds(ids);
        return Result.ok();
    }

    @Override
    public void export(List<ScheduleJobLogTbBO> scheduleJobLogTbBOS, HttpServletResponse response) {
        log.debug("[{}]正在导出接口数据，数据 -> {}", ACContext.getUserContext().getUsername(), scheduleJobLogTbBOS.toString());
        //创建工作簿
        HSSFWorkbook workbook = new HSSFWorkbook();
        //创建sheet
        HSSFSheet sheet = workbook.createSheet("任务日志表");
        //定义表头，文件名，向表头中set表头标题
        String excelName = System.currentTimeMillis() + SysConstant.EXCELX_SUFFIX;
        HSSFRow row = sheet.createRow(0);
        String[] excelHeaders = new String[]{"ID", "任务ID", "任务名称", "任务实现类", "任务组ID", "任务类型", "任务参数", "任务耗时(ms)", "响应码",
                "响应描述", "执行时间"};
        for (int i = 0; i < excelHeaders.length; i++) {
            row.createCell(i).setCellValue(new HSSFRichTextString(excelHeaders[i])); //set入Unicode编码的字符串
        }
        //创建单元格，将查询到的接口数据set入
        int excelDataNum = 1; //表格数据行数（第一行）
        for (ScheduleJobLogTbBO scheduleJobLogTbBO : scheduleJobLogTbBOS) {
            HSSFRow dataRow = sheet.createRow(excelDataNum);
            dataRow.createCell(0).setCellValue(scheduleJobLogTbBO.getId());
            dataRow.createCell(1).setCellValue(scheduleJobLogTbBO.getJobId());
            dataRow.createCell(2).setCellValue(scheduleJobLogTbBO.getJobName());
            dataRow.createCell(3).setCellValue(scheduleJobLogTbBO.getBeanName());
            dataRow.createCell(4).setCellValue(scheduleJobLogTbBO.getGroupId());
            dataRow.createCell(5).setCellValue(scheduleJobLogTbBO.getJobType());
            dataRow.createCell(6).setCellValue(scheduleJobLogTbBO.getJobParams());
            dataRow.createCell(7).setCellValue(scheduleJobLogTbBO.getJobTime() == null ? "" :
                    scheduleJobLogTbBO.getJobTime().toPlainString());
            dataRow.createCell(8).setCellValue(scheduleJobLogTbBO.getResultCode());
            dataRow.createCell(9).setCellValue(scheduleJobLogTbBO.getResultMsg());
            dataRow.createCell(10).setCellValue(DateUtil.sdfDateTime(scheduleJobLogTbBO.getExecuteTime()));
            excelDataNum++;
        }
        //构建response
        try {
            response.setContentType("application/octet-stream");
            response.setCharacterEncoding("utf-8");
            response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(excelName, "utf-8"));
            response.flushBuffer();
            workbook.write(response.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
        log.debug("[{}]导出接口数据完毕！", ACContext.getUserContext().getUsername());
    }

    @Override
    public Result queryList(ScheduleJobLogTbBO scheduleJobLogTbBO) {
        PageResult<ScheduleJobLogTbBO> pageResult = new PageResult<ScheduleJobLogTbBO>().setCurPageAndSize(scheduleJobLogTbBO
                .calCurPage());
        LambdaQueryWrapper<ScheduleJobLogTbEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.isNotBlank(scheduleJobLogTbBO.getJobName()), ScheduleJobLogTbEntity::getJobName,
                SysConstant.SPECIAL_CHAR_1 + scheduleJobLogTbBO.getJobName() + SysConstant.SPECIAL_CHAR_1);
        queryWrapper.last(SysConstant.DB_KEYWORD_LIMIT + scheduleJobLogTbBO.getCurPage() + SysConstant.SPECIAL_CHAR_3 +
                scheduleJobLogTbBO.getSize()); //等价于limit 1,5 （有SQL注入风险）
        queryWrapper.orderByDesc(ScheduleJobLogTbEntity::getId);
        List<ScheduleJobLogTbEntity> scheduleJobLogTbEntityList = scheduleJobLogTbMapper.selectList(queryWrapper);
        pageResult.setTotals(getTotalJobLogs(scheduleJobLogTbBO));
        List<ScheduleJobLogTbBO> scheduleJobLogTbBOS = BeanOprUtils.copyListProperties(scheduleJobLogTbEntityList,
                ScheduleJobLogTbBO::new);
        scheduleJobLogTbBOS.forEach(s ->
                    s.setJobType(SysConstant.JOB_TYPE_ENUM_STRING_MAP.get(JobTypeEnum.FIXTIME).equals(s.getJobType()) ? "定时" : "实时"));
        pageResult.setData(scheduleJobLogTbBOS);
        return Result.ok(pageResult);
    }

    private Integer getTotalJobLogs(ScheduleJobLogTbBO scheduleJobLogTbBO) {
        LambdaQueryWrapper<ScheduleJobLogTbEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.isNotBlank(scheduleJobLogTbBO.getJobName()), ScheduleJobLogTbEntity::getJobName,
                SysConstant.SPECIAL_CHAR_1 + scheduleJobLogTbBO.getJobName() + SysConstant.SPECIAL_CHAR_1);
        return scheduleJobLogTbMapper.selectCount(queryWrapper);
    }

}